﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace vJine.Core.Task {
    /// <summary>
    /// 进程配置
    /// </summary>
    public class ProcessConfig {
        /// <summary>
        /// 进程名称
        /// </summary>
        public string name { get; set; }
        /// <summary>
        /// 命令行
        /// </summary>
        public string cmd { get; set; }
        /// <summary>
        /// 命令参数
        /// </summary>
        public string arg { get; set; }
        /// <summary>
        /// 参数选项
        /// </summary>
        public string[] arg_params { get; set; }
        /// <summary>
        /// 窗口可见
        /// </summary>
        public bool visible { get; set; }
        /// <summary>
        /// 环境变量键值对
        /// </summary>
        public string[] ENV_VARS { get; set; }

        Process PROCESS = null;
        /// <summary>
        /// 运行中：如果为True，则进程正在运行
        /// </summary>
        public bool IsRunning {
            get {
                lock(this) {
                    if(this.PROCESS == null) {
                        return false;
                    } else {
                        return !this.PROCESS.HasExited;
                    }
                }
            }
        }

        /// <summary>
        /// 进程退出事件：进程退出时触发此事件
        /// </summary>
        public event Exec<ProcessConfig> OnExit;

        /// <summary>
        /// 启动进程
        /// </summary>
        /// <returns>如果进程已启动，则返回True</returns>
        public bool Start() {
            lock(this) {
                if(this.IsRunning) {
                    return true;
                }

                if(this.PROCESS == null) {
                    this.PROCESS = new Process();
                    this.PROCESS.Exited += (object sender, EventArgs e) => {
                        try {
                            this.OnExit(this);
                        } catch(Exception ex) {
                            string er_msg = ex.Message;
                        }
                    };
                }

                this.PROCESS.EnableRaisingEvents = true;
                ProcessStartInfo startInfo = this.PROCESS.StartInfo;
                {
                    if(this.ENV_VARS != null) {
                        for(int i = 0, len = this.ENV_VARS.Length; i < len; i += 2) {
                            string key = this.ENV_VARS[i];
                            string value = this.ENV_VARS[i + 1];
                            if(startInfo.EnvironmentVariables.ContainsKey(key)) {
                                startInfo.EnvironmentVariables[key] = value;
                            } else {
                                startInfo.EnvironmentVariables.Add(key, value);
                            }
                        }
                    }
                    startInfo.FileName = this.cmd;
                    startInfo.Arguments = string.Format(this.arg, this.arg_params);
                    startInfo.CreateNoWindow = this.visible;
                    startInfo.UseShellExecute = false;

                    if(this.visible) {
                        startInfo.WindowStyle = ProcessWindowStyle.Minimized;
                    }

                }

                try {
                    this.PROCESS.Start();
                    return true;
                } catch (Exception ex) {
                    return false;
                }
            }
        }

        /// <summary>
        /// 停止进程
        /// </summary>
        /// <returns>如果进程已停止，则返回True</returns>
        public bool Stop() {
            lock(this) {
                if(!this.IsRunning) {
                    return true;
                }
                try {
                    this.PROCESS.EnableRaisingEvents = false;
                    this.PROCESS.Kill();
                    return true;
                } catch {
                    return false;
                }
            }
        }

        /// <summary>
        /// 重启进程
        /// </summary>
        /// <returns>如果进程已启动，则返回True</returns>
        public bool Restart() {
            lock(this) {
                if(!this.IsRunning) {
                    return false;
                }

                this.Stop();

                return this.Start();
            }
        }
    }
}
